import { Injectable, HttpException, HttpStatus } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { ArticleEntity } from './article.entity';
import { CommentEntity } from './comment.entity';
import { CacheService } from '../cache/cache.service';
import { UsersEntity } from '../users/users.entity';
import {
  getConnection,
  createQueryBuilder,
  getRepository,
  getManager,
} from 'typeorm';
import { ICommonListContainer } from '../utils/relust/relust';
import * as moment from 'moment';

@Injectable()
export class ArticleService {
  constructor(
    @InjectRepository(ArticleEntity)
    private articleRepository: Repository<ArticleEntity>,
    @InjectRepository(CommentEntity)
    private commentRepository: Repository<CommentEntity>,
    private readonly cache: CacheService,
  ) {}

  async findAll(pageNum = 1, pageSize = 10, zd = '') {
    let qb = this.articleRepository
      .createQueryBuilder('article')
      .leftJoinAndMapOne(
        'article.author',
        'users',
        'user',
        'user.id = article.userId',
      )
      .cache(30000);

    if (zd) {
      qb = qb.where('article.name like :name', { name: '%' + zd + '%' });
    }
    // console.log(
    //   qb
    //     .skip(pageSize * (pageNum - 1))
    //     .take(pageSize)
    //     .leftJoinAndSelect('comment', 'com', 'com.topic_id = article.id')
    //     .getSql(),
    // );
    // console.log(
    //   this.commentRepository
    //     .createQueryBuilder('comment')
    //     .select('comment.topic_id')
    //     .groupBy('comment.topic_id')
    //     .having('comment.count > 0')
    //     .getSql(),
    // );
    qb = qb
      .skip(pageSize * (pageNum - 1))
      .take(pageSize)
      .orderBy('article.time', 'DESC');
    // .leftJoinAndMapOne(
    //   'article.com',
    //   'comment',
    //   'com',
    //   'com.topic_id = article.id',
    // );

    const pls = await this.commentRepository.query(
      'select topic_id,count(*) as count from comment group by topic_id having count>0;',
    );
    const [list, total] = await qb.getManyAndCount();
    list.forEach((item) => {
      item.wenben =
        item.wenben.replace(/<.*?>/g, '').substr(0, 255) +
        (item.wenben.length > 255 ? '...' : '');
    });
    if (list.length) {
      for (const item of list) {
        const isHit = await this.cache.general('hget', 'article_hit', item.id);

        if (isHit) {
          item.hit = Number(isHit) + 1;
        }

        item.time = moment(item.time).format('YYYY-MM-DD');
        item.pls = pls.find((items) => items.topic_id === item.id)
          ? pls.find((items) => items.topic_id === item.id).count
          : '0';
      }
    }
    return {
      pageSize,
      pageNum,
      pages: Math.ceil(total / pageSize),
      total,
      list,
    };
  }

  async remove(id: number) {
    await this.articleRepository.delete(id);
    return `成功！`;
  }

  async addText(body, user) {
    const article = new ArticleEntity();
    article.name = body.name;
    article.wenben = body.content;
    article.userId = user.userId;
    return this.articleRepository.save(article);
  }

  async getDetail(id, user) {
    const data = await this.articleRepository.findOne({ where: { id } });

    if (data) {
      const pls = await this.commentRepository.query(
        'select topic_id,count(*) as count from comment group by topic_id having count>0;',
      );
      data.pls = pls.find((item) => item.topic_id === data.id)
        ? pls.find((item) => item.topic_id === data.id).count
        : '0';

      if (user) {
        await this.cache.latelylist(data, user); //记录点击最近新闻
      }

      const isHit = await this.cache.general('hget', 'article_hit', data.id);

      if (isHit) {
        //存在走缓存++
        this.cache.general('hincrby', 'article_hit', data.id, 1);
        data.hit = Number(isHit) + 1;
      } else {
        //不存在设置缓存++
        this.cache.general('hset', 'article_hit', data.id, data.hit);
        //this.articleRepository.update(data.id, { hit: data.hit + 1 });
      }
    }

    return data;
  }

  async commentAdd(body, user) {
    const data = new CommentEntity();

    data.content = body.content;
    data.to_uid = body.to_uid || null;
    data.topic_type = body.type || 0;
    data.topic_id = body.wzid;

    data.authorId = user.userId;
    return this.commentRepository.save(data);
  }

  async commentList(id) {
    //getManager().query('select * from cc'); 全局查
    const cc = await this.commentRepository
      .createQueryBuilder('u')
      .where('u.topic_id = :id', { id })
      .leftJoinAndMapOne('u.author', 'users', 'user', 'u.authorId = user.id')
      .orderBy('u.time', 'DESC')
      .getMany();

    return cc;
  }

  async syncData(data) {
    const keys = Object.keys(data);
    const arr = [];
    for (const key in data) {
      arr.push(`WHEN ${key} THEN ${data[key]}`);
    }
    const qb = await this.articleRepository.query(
      `UPDATE article SET hit = CASE id ${arr.join(
        ' ',
      )} END WHERE id IN (${keys.join(',')})`,
    );
  }

  async lately(user) {
    const isExists = await this.cache.general(
      'lrange',
      'lately:' + user.userId,
      0,
      4,
    );

    if (isExists) {
      return isExists.map((item) => {
        return {
          id: item.split('---')[0],
          name: item.split('---')[1],
        };
      });
    } else {
      return null;
    }
  }
}
